package array;


/**
 * @author huang (1431471764@qq.com)
 * @date 2025/8/6 17:11
 */

/**
 * @author 随风coding
 * @version 1.0
 * @date 2025/8/6 17:11
 * @description
 */
public class MinSizeSubarraySum {
    /**
     * 找到数组中和大于等于 target 且长度最小的连续子数组
     *
     * @param arr    输入的正整数数组（假设数组元素均为正整数）
     * @param target 需要满足的最小和阈值
     * @return 最小子数组的长度；若不存在符合条件的子数组，返回 0
     */
    public static int findMinSubarrayLen(int[] arr, int target) {
        // 处理数组为空的边界情况
        if (arr == null || arr.length == 0) {
            return 0;
        }

        int left = 0;          // 滑动窗口的左边界指针
        int currentSum = 0;    // 当前窗口内元素的和
        int minLength = Integer.MAX_VALUE;  // 记录最小长度（初始设为最大整数）

        // 右指针遍历数组，扩展窗口右边界
        for (int right = 0; right < arr.length; right++) {
            currentSum += arr[right];  // 将当前右指针元素加入窗口和

            // 当窗口和满足条件时，尝试收缩左边界以找到更小的窗口
            while (currentSum >= target) {
                // 计算当前窗口的长度（右指针 - 左指针 + 1）
                int currentWindowLength = right - left + 1;
                // 更新最小长度（取当前长度和历史最小长度的较小值）
                minLength = Math.min(minLength, currentWindowLength);

                // 收缩左边界：从窗口和中移除左指针元素，并移动左指针
                currentSum -= arr[left];
                left++;
            }
        }

        // 如果 minLength 未被更新（说明没有符合条件的子数组），返回 0；否则返回最小长度
        return minLength == Integer.MAX_VALUE ? 0 : minLength;
    }
}
